home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / httplib.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-29  |  39KB  |  1,381 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''HTTP/1.1 client library
  5.  
  6. <intro stuff goes here>
  7. <other stuff, too>
  8.  
  9. HTTPConnection goes through a number of "states", which define when a client
  10. may legally make another request or fetch the response for a particular
  11. request. This diagram details these state transitions:
  12.  
  13.     (null)
  14.       |
  15.       | HTTPConnection()
  16.       v
  17.     Idle
  18.       |
  19.       | putrequest()
  20.       v
  21.     Request-started
  22.       |
  23.       | ( putheader() )*  endheaders()
  24.       v
  25.     Request-sent
  26.       |
  27.       | response = getresponse()
  28.       v
  29.     Unread-response   [Response-headers-read]
  30.       |\\____________________
  31.       |                     |
  32.       | response.read()     | putrequest()
  33.       v                     v
  34.     Idle                  Req-started-unread-response
  35.                      ______/|
  36.                    /        |
  37.    response.read() |        | ( putheader() )*  endheaders()
  38.                    v        v
  39.        Request-started    Req-sent-unread-response
  40.                             |
  41.                             | response.read()
  42.                             v
  43.                           Request-sent
  44.  
  45. This diagram presents the following rules:
  46.   -- a second request may not be started until {response-headers-read}
  47.   -- a response [object] cannot be retrieved until {request-sent}
  48.   -- there is no differentiation between an unread response body and a
  49.      partially read response body
  50.  
  51. Note: this enforcement is applied by the HTTPConnection class. The
  52.       HTTPResponse class does not enforce this state machine, which
  53.       implies sophisticated clients may accelerate the request/response
  54.       pipeline. Caution should be taken, though: accelerating the states
  55.       beyond the above pattern may imply knowledge of the server\'s
  56.       connection-close behavior for certain requests. For example, it
  57.       is impossible to tell whether the server will close the connection
  58.       UNTIL the response headers have been read; this means that further
  59.       requests cannot be placed into the pipeline until it is known that
  60.       the server will NOT be closing the connection.
  61.  
  62. Logical State                  __state            __response
  63. -------------                  -------            ----------
  64. Idle                           _CS_IDLE           None
  65. Request-started                _CS_REQ_STARTED    None
  66. Request-sent                   _CS_REQ_SENT       None
  67. Unread-response                _CS_IDLE           <response_class>
  68. Req-started-unread-response    _CS_REQ_STARTED    <response_class>
  69. Req-sent-unread-response       _CS_REQ_SENT       <response_class>
  70. '''
  71. import errno
  72. import mimetools
  73. import socket
  74. from urlparse import urlsplit
  75.  
  76. try:
  77.     from cStringIO import StringIO
  78. except ImportError:
  79.     from StringIO import StringIO
  80.  
  81. __all__ = [
  82.     'HTTP',
  83.     'HTTPResponse',
  84.     'HTTPConnection',
  85.     'HTTPSConnection',
  86.     'HTTPException',
  87.     'NotConnected',
  88.     'UnknownProtocol',
  89.     'UnknownTransferEncoding',
  90.     'UnimplementedFileMode',
  91.     'IncompleteRead',
  92.     'InvalidURL',
  93.     'ImproperConnectionState',
  94.     'CannotSendRequest',
  95.     'CannotSendHeader',
  96.     'ResponseNotReady',
  97.     'BadStatusLine',
  98.     'error',
  99.     'responses']
  100. HTTP_PORT = 80
  101. HTTPS_PORT = 443
  102. _UNKNOWN = 'UNKNOWN'
  103. _CS_IDLE = 'Idle'
  104. _CS_REQ_STARTED = 'Request-started'
  105. _CS_REQ_SENT = 'Request-sent'
  106. CONTINUE = 100
  107. SWITCHING_PROTOCOLS = 101
  108. PROCESSING = 102
  109. OK = 200
  110. CREATED = 201
  111. ACCEPTED = 202
  112. NON_AUTHORITATIVE_INFORMATION = 203
  113. NO_CONTENT = 204
  114. RESET_CONTENT = 205
  115. PARTIAL_CONTENT = 206
  116. MULTI_STATUS = 207
  117. IM_USED = 226
  118. MULTIPLE_CHOICES = 300
  119. MOVED_PERMANENTLY = 301
  120. FOUND = 302
  121. SEE_OTHER = 303
  122. NOT_MODIFIED = 304
  123. USE_PROXY = 305
  124. TEMPORARY_REDIRECT = 307
  125. BAD_REQUEST = 400
  126. UNAUTHORIZED = 401
  127. PAYMENT_REQUIRED = 402
  128. FORBIDDEN = 403
  129. NOT_FOUND = 404
  130. METHOD_NOT_ALLOWED = 405
  131. NOT_ACCEPTABLE = 406
  132. PROXY_AUTHENTICATION_REQUIRED = 407
  133. REQUEST_TIMEOUT = 408
  134. CONFLICT = 409
  135. GONE = 410
  136. LENGTH_REQUIRED = 411
  137. PRECONDITION_FAILED = 412
  138. REQUEST_ENTITY_TOO_LARGE = 413
  139. REQUEST_URI_TOO_LONG = 414
  140. UNSUPPORTED_MEDIA_TYPE = 415
  141. REQUESTED_RANGE_NOT_SATISFIABLE = 416
  142. EXPECTATION_FAILED = 417
  143. UNPROCESSABLE_ENTITY = 422
  144. LOCKED = 423
  145. FAILED_DEPENDENCY = 424
  146. UPGRADE_REQUIRED = 426
  147. INTERNAL_SERVER_ERROR = 500
  148. NOT_IMPLEMENTED = 501
  149. BAD_GATEWAY = 502
  150. SERVICE_UNAVAILABLE = 503
  151. GATEWAY_TIMEOUT = 504
  152. HTTP_VERSION_NOT_SUPPORTED = 505
  153. INSUFFICIENT_STORAGE = 507
  154. NOT_EXTENDED = 510
  155. responses = {
  156.     100: 'Continue',
  157.     101: 'Switching Protocols',
  158.     200: 'OK',
  159.     201: 'Created',
  160.     202: 'Accepted',
  161.     203: 'Non-Authoritative Information',
  162.     204: 'No Content',
  163.     205: 'Reset Content',
  164.     206: 'Partial Content',
  165.     300: 'Multiple Choices',
  166.     301: 'Moved Permanently',
  167.     302: 'Found',
  168.     303: 'See Other',
  169.     304: 'Not Modified',
  170.     305: 'Use Proxy',
  171.     306: '(Unused)',
  172.     307: 'Temporary Redirect',
  173.     400: 'Bad Request',
  174.     401: 'Unauthorized',
  175.     402: 'Payment Required',
  176.     403: 'Forbidden',
  177.     404: 'Not Found',
  178.     405: 'Method Not Allowed',
  179.     406: 'Not Acceptable',
  180.     407: 'Proxy Authentication Required',
  181.     408: 'Request Timeout',
  182.     409: 'Conflict',
  183.     410: 'Gone',
  184.     411: 'Length Required',
  185.     412: 'Precondition Failed',
  186.     413: 'Request Entity Too Large',
  187.     414: 'Request-URI Too Long',
  188.     415: 'Unsupported Media Type',
  189.     416: 'Requested Range Not Satisfiable',
  190.     417: 'Expectation Failed',
  191.     500: 'Internal Server Error',
  192.     501: 'Not Implemented',
  193.     502: 'Bad Gateway',
  194.     503: 'Service Unavailable',
  195.     504: 'Gateway Timeout',
  196.     505: 'HTTP Version Not Supported' }
  197. MAXAMOUNT = 1048576
  198.  
  199. class HTTPMessage(mimetools.Message):
  200.     
  201.     def addheader(self, key, value):
  202.         '''Add header for field key handling repeats.'''
  203.         prev = self.dict.get(key)
  204.         if prev is None:
  205.             self.dict[key] = value
  206.         else:
  207.             combined = ', '.join((prev, value))
  208.             self.dict[key] = combined
  209.  
  210.     
  211.     def addcontinue(self, key, more):
  212.         '''Add more field data from a continuation line.'''
  213.         prev = self.dict[key]
  214.         self.dict[key] = prev + '\n ' + more
  215.  
  216.     
  217.     def readheaders(self):
  218.         '''Read header lines.
  219.  
  220.         Read header lines up to the entirely blank line that terminates them.
  221.         The (normally blank) line that ends the headers is skipped, but not
  222.         included in the returned list.  If a non-header line ends the headers,
  223.         (which is an error), an attempt is made to backspace over it; it is
  224.         never included in the returned list.
  225.  
  226.         The variable self.status is set to the empty string if all went well,
  227.         otherwise it is an error message.  The variable self.headers is a
  228.         completely uninterpreted list of lines contained in the header (so
  229.         printing them will reproduce the header exactly as it appears in the
  230.         file).
  231.  
  232.         If multiple header fields with the same name occur, they are combined
  233.         according to the rules in RFC 2616 sec 4.2:
  234.  
  235.         Appending each subsequent field-value to the first, each separated
  236.         by a comma. The order in which header fields with the same field-name
  237.         are received is significant to the interpretation of the combined
  238.         field value.
  239.         '''
  240.         self.dict = { }
  241.         self.unixfrom = ''
  242.         self.headers = hlist = []
  243.         self.status = ''
  244.         headerseen = ''
  245.         firstline = 1
  246.         startofline = None
  247.         unread = None
  248.         tell = None
  249.         if hasattr(self.fp, 'unread'):
  250.             unread = self.fp.unread
  251.         elif self.seekable:
  252.             tell = self.fp.tell
  253.         
  254.         while True:
  255.             if tell:
  256.                 
  257.                 try:
  258.                     startofline = tell()
  259.                 except IOError:
  260.                     startofline = None
  261.                     tell = None
  262.                     self.seekable = 0
  263.                 except:
  264.                     None<EXCEPTION MATCH>IOError
  265.                 
  266.  
  267.             None<EXCEPTION MATCH>IOError
  268.             line = self.fp.readline()
  269.             if not line:
  270.                 self.status = 'EOF in headers'
  271.                 break
  272.             
  273.             if firstline and line.startswith('From '):
  274.                 self.unixfrom = self.unixfrom + line
  275.                 continue
  276.             
  277.             firstline = 0
  278.             if headerseen and line[0] in ' \t':
  279.                 hlist.append(line)
  280.                 self.addcontinue(headerseen, line.strip())
  281.                 continue
  282.             elif self.iscomment(line):
  283.                 continue
  284.             elif self.islast(line):
  285.                 break
  286.             
  287.             headerseen = self.isheader(line)
  288.             if headerseen:
  289.                 hlist.append(line)
  290.                 self.addheader(headerseen, line[len(headerseen) + 1:].strip())
  291.                 continue
  292.                 continue
  293.             if not self.dict:
  294.                 self.status = 'No headers'
  295.             else:
  296.                 self.status = 'Non-header line where header expected'
  297.             if unread:
  298.                 unread(line)
  299.             elif tell:
  300.                 self.fp.seek(startofline)
  301.             else:
  302.                 self.status = self.status + '; bad seek'
  303.             break
  304.  
  305.  
  306.  
  307. class HTTPResponse:
  308.     
  309.     def __init__(self, sock, debuglevel = 0, strict = 0, method = None):
  310.         self.fp = sock.makefile('rb', 0)
  311.         self.debuglevel = debuglevel
  312.         self.strict = strict
  313.         self._method = method
  314.         self.msg = None
  315.         self.version = _UNKNOWN
  316.         self.status = _UNKNOWN
  317.         self.reason = _UNKNOWN
  318.         self.chunked = _UNKNOWN
  319.         self.chunk_left = _UNKNOWN
  320.         self.length = _UNKNOWN
  321.         self.will_close = _UNKNOWN
  322.  
  323.     
  324.     def _read_status(self):
  325.         line = self.fp.readline()
  326.         if self.debuglevel > 0:
  327.             print 'reply:', repr(line)
  328.         
  329.         if not line:
  330.             raise BadStatusLine(line)
  331.         
  332.         
  333.         try:
  334.             (version, status, reason) = line.split(None, 2)
  335.         except ValueError:
  336.             
  337.             try:
  338.                 (version, status) = line.split(None, 1)
  339.                 reason = ''
  340.             except ValueError:
  341.                 version = ''
  342.             except:
  343.                 None<EXCEPTION MATCH>ValueError
  344.             
  345.  
  346.             None<EXCEPTION MATCH>ValueError
  347.  
  348.         if not version.startswith('HTTP/'):
  349.             if self.strict:
  350.                 self.close()
  351.                 raise BadStatusLine(line)
  352.             else:
  353.                 self.fp = LineAndFileWrapper(line, self.fp)
  354.                 return ('HTTP/0.9', 200, '')
  355.         
  356.         
  357.         try:
  358.             status = int(status)
  359.             if status < 100 or status > 999:
  360.                 raise BadStatusLine(line)
  361.         except ValueError:
  362.             raise BadStatusLine(line)
  363.  
  364.         return (version, status, reason)
  365.  
  366.     
  367.     def begin(self):
  368.         if self.msg is not None:
  369.             return None
  370.         
  371.         while True:
  372.             (version, status, reason) = self._read_status()
  373.             if status != CONTINUE:
  374.                 break
  375.             
  376.             while True:
  377.                 skip = self.fp.readline().strip()
  378.                 if not skip:
  379.                     break
  380.                 
  381.                 if self.debuglevel > 0:
  382.                     print 'header:', skip
  383.                     continue
  384.         self.status = status
  385.         self.reason = reason.strip()
  386.         if version == 'HTTP/1.0':
  387.             self.version = 10
  388.         elif version.startswith('HTTP/1.'):
  389.             self.version = 11
  390.         elif version == 'HTTP/0.9':
  391.             self.version = 9
  392.         else:
  393.             raise UnknownProtocol(version)
  394.         if self.version == 9:
  395.             self.length = None
  396.             self.chunked = 0
  397.             self.will_close = 1
  398.             self.msg = HTTPMessage(StringIO())
  399.             return None
  400.         
  401.         self.msg = HTTPMessage(self.fp, 0)
  402.         if self.debuglevel > 0:
  403.             for hdr in self.msg.headers:
  404.                 print 'header:', hdr,
  405.             
  406.         
  407.         self.msg.fp = None
  408.         tr_enc = self.msg.getheader('transfer-encoding')
  409.         if tr_enc and tr_enc.lower() == 'chunked':
  410.             self.chunked = 1
  411.             self.chunk_left = None
  412.         else:
  413.             self.chunked = 0
  414.         self.will_close = self._check_close()
  415.         length = self.msg.getheader('content-length')
  416.         if length and not (self.chunked):
  417.             
  418.             try:
  419.                 self.length = int(length)
  420.             except ValueError:
  421.                 self.length = None
  422.             except:
  423.                 None<EXCEPTION MATCH>ValueError
  424.             
  425.  
  426.         None<EXCEPTION MATCH>ValueError
  427.         self.length = None
  428.         if not status == NO_CONTENT and status == NOT_MODIFIED:
  429.             if status <= status:
  430.                 pass
  431.             elif status < 200 or self._method == 'HEAD':
  432.                 self.length = 0
  433.             
  434.         if not (self.will_close) and not (self.chunked) and self.length is None:
  435.             self.will_close = 1
  436.         
  437.  
  438.     
  439.     def _check_close(self):
  440.         conn = self.msg.getheader('connection')
  441.         if self.version == 11:
  442.             conn = self.msg.getheader('connection')
  443.             if conn and 'close' in conn.lower():
  444.                 return True
  445.             
  446.             return False
  447.         
  448.         if self.msg.getheader('keep-alive'):
  449.             return False
  450.         
  451.         if conn and 'keep-alive' in conn.lower():
  452.             return False
  453.         
  454.         pconn = self.msg.getheader('proxy-connection')
  455.         if pconn and 'keep-alive' in pconn.lower():
  456.             return False
  457.         
  458.         return True
  459.  
  460.     
  461.     def close(self):
  462.         if self.fp:
  463.             self.fp.close()
  464.             self.fp = None
  465.         
  466.  
  467.     
  468.     def isclosed(self):
  469.         return self.fp is None
  470.  
  471.     
  472.     def read(self, amt = None):
  473.         if self.fp is None:
  474.             return ''
  475.         
  476.         if self.chunked:
  477.             return self._read_chunked(amt)
  478.         
  479.         if amt is None:
  480.             if self.length is None:
  481.                 s = self.fp.read()
  482.             else:
  483.                 s = self._safe_read(self.length)
  484.                 self.length = 0
  485.             self.close()
  486.             return s
  487.         
  488.         if self.length is not None:
  489.             if amt > self.length:
  490.                 amt = self.length
  491.             
  492.         
  493.         s = self.fp.read(amt)
  494.         if self.length is not None:
  495.             self.length -= len(s)
  496.         
  497.         return s
  498.  
  499.     
  500.     def _read_chunked(self, amt):
  501.         if not self.chunked != _UNKNOWN:
  502.             raise AssertionError
  503.         chunk_left = self.chunk_left
  504.         value = ''
  505.         while True:
  506.             if chunk_left is None:
  507.                 line = self.fp.readline()
  508.                 i = line.find(';')
  509.                 if i >= 0:
  510.                     line = line[:i]
  511.                 
  512.                 chunk_left = int(line, 16)
  513.                 if chunk_left == 0:
  514.                     break
  515.                 
  516.             
  517.             if amt is None:
  518.                 value += self._safe_read(chunk_left)
  519.             elif amt < chunk_left:
  520.                 value += self._safe_read(amt)
  521.                 self.chunk_left = chunk_left - amt
  522.                 return value
  523.             elif amt == chunk_left:
  524.                 value += self._safe_read(amt)
  525.                 self._safe_read(2)
  526.                 self.chunk_left = None
  527.                 return value
  528.             else:
  529.                 value += self._safe_read(chunk_left)
  530.                 amt -= chunk_left
  531.             self._safe_read(2)
  532.             chunk_left = None
  533.         while True:
  534.             line = self.fp.readline()
  535.             if not line:
  536.                 break
  537.             
  538.             if line == '\r\n':
  539.                 break
  540.                 continue
  541.         self.close()
  542.         return value
  543.  
  544.     
  545.     def _safe_read(self, amt):
  546.         '''Read the number of bytes requested, compensating for partial reads.
  547.  
  548.         Normally, we have a blocking socket, but a read() can be interrupted
  549.         by a signal (resulting in a partial read).
  550.  
  551.         Note that we cannot distinguish between EOF and an interrupt when zero
  552.         bytes have been read. IncompleteRead() will be raised in this
  553.         situation.
  554.  
  555.         This function should be used when <amt> bytes "should" be present for
  556.         reading. If the bytes are truly not available (due to EOF), then the
  557.         IncompleteRead exception can be used to detect the problem.
  558.         '''
  559.         s = []
  560.         while amt > 0:
  561.             chunk = self.fp.read(min(amt, MAXAMOUNT))
  562.             if not chunk:
  563.                 raise IncompleteRead(s)
  564.             
  565.             s.append(chunk)
  566.             amt -= len(chunk)
  567.         return ''.join(s)
  568.  
  569.     
  570.     def getheader(self, name, default = None):
  571.         if self.msg is None:
  572.             raise ResponseNotReady()
  573.         
  574.         return self.msg.getheader(name, default)
  575.  
  576.     
  577.     def getheaders(self):
  578.         '''Return list of (header, value) tuples.'''
  579.         if self.msg is None:
  580.             raise ResponseNotReady()
  581.         
  582.         return self.msg.items()
  583.  
  584.  
  585.  
  586. class HTTPConnection:
  587.     _http_vsn = 11
  588.     _http_vsn_str = 'HTTP/1.1'
  589.     response_class = HTTPResponse
  590.     default_port = HTTP_PORT
  591.     auto_open = 1
  592.     debuglevel = 0
  593.     strict = 0
  594.     
  595.     def __init__(self, host, port = None, strict = None):
  596.         self.sock = None
  597.         self._buffer = []
  598.         self._HTTPConnection__response = None
  599.         self._HTTPConnection__state = _CS_IDLE
  600.         self._method = None
  601.         self._set_hostport(host, port)
  602.         if strict is not None:
  603.             self.strict = strict
  604.         
  605.  
  606.     
  607.     def _set_hostport(self, host, port):
  608.         if port is None:
  609.             i = host.rfind(':')
  610.             j = host.rfind(']')
  611.             if i > j:
  612.                 
  613.                 try:
  614.                     port = int(host[i + 1:])
  615.                 except ValueError:
  616.                     raise InvalidURL("nonnumeric port: '%s'" % host[i + 1:])
  617.  
  618.                 host = host[:i]
  619.             else:
  620.                 port = self.default_port
  621.             if host and host[0] == '[' and host[-1] == ']':
  622.                 host = host[1:-1]
  623.             
  624.         
  625.         self.host = host
  626.         self.port = port
  627.  
  628.     
  629.     def set_debuglevel(self, level):
  630.         self.debuglevel = level
  631.  
  632.     
  633.     def connect(self):
  634.         '''Connect to the host and port specified in __init__.'''
  635.         msg = 'getaddrinfo returns an empty list'
  636.         for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM):
  637.             (af, socktype, proto, canonname, sa) = res
  638.             
  639.             try:
  640.                 self.sock = socket.socket(af, socktype, proto)
  641.                 if self.debuglevel > 0:
  642.                     print 'connect: (%s, %s)' % (self.host, self.port)
  643.                 
  644.                 self.sock.connect(sa)
  645.             except socket.error:
  646.                 msg = None
  647.                 if self.debuglevel > 0:
  648.                     print 'connect fail:', (self.host, self.port)
  649.                 
  650.                 if self.sock:
  651.                     self.sock.close()
  652.                 
  653.                 self.sock = None
  654.                 continue
  655.  
  656.             break
  657.         
  658.         if not self.sock:
  659.             raise socket.error, msg
  660.         
  661.  
  662.     
  663.     def close(self):
  664.         '''Close the connection to the HTTP server.'''
  665.         if self.sock:
  666.             self.sock.close()
  667.             self.sock = None
  668.         
  669.         if self._HTTPConnection__response:
  670.             self._HTTPConnection__response.close()
  671.             self._HTTPConnection__response = None
  672.         
  673.         self._HTTPConnection__state = _CS_IDLE
  674.  
  675.     
  676.     def send(self, str):
  677.         """Send `str' to the server."""
  678.         if self.sock is None:
  679.             if self.auto_open:
  680.                 self.connect()
  681.             else:
  682.                 raise NotConnected()
  683.         
  684.         if self.debuglevel > 0:
  685.             print 'send:', repr(str)
  686.         
  687.         
  688.         try:
  689.             self.sock.sendall(str)
  690.         except socket.error:
  691.             v = None
  692.             if v[0] == 32:
  693.                 self.close()
  694.             
  695.             raise 
  696.  
  697.  
  698.     
  699.     def _output(self, s):
  700.         '''Add a line of output to the current request buffer.
  701.  
  702.         Assumes that the line does *not* end with \\r\\n.
  703.         '''
  704.         self._buffer.append(s)
  705.  
  706.     
  707.     def _send_output(self):
  708.         '''Send the currently buffered request and clear the buffer.
  709.  
  710.         Appends an extra \\r\\n to the buffer.
  711.         '''
  712.         self._buffer.extend(('', ''))
  713.         msg = '\r\n'.join(self._buffer)
  714.         del self._buffer[:]
  715.         self.send(msg)
  716.  
  717.     
  718.     def putrequest(self, method, url, skip_host = 0, skip_accept_encoding = 0):
  719.         """Send a request to the server.
  720.  
  721.         `method' specifies an HTTP request method, e.g. 'GET'.
  722.         `url' specifies the object being requested, e.g. '/index.html'.
  723.         `skip_host' if True does not add automatically a 'Host:' header
  724.         `skip_accept_encoding' if True does not add automatically an
  725.            'Accept-Encoding:' header
  726.         """
  727.         if self._HTTPConnection__response and self._HTTPConnection__response.isclosed():
  728.             self._HTTPConnection__response = None
  729.         
  730.         if self._HTTPConnection__state == _CS_IDLE:
  731.             self._HTTPConnection__state = _CS_REQ_STARTED
  732.         else:
  733.             raise CannotSendRequest()
  734.         self._method = method
  735.         if not url:
  736.             url = '/'
  737.         
  738.         str = '%s %s %s' % (method, url, self._http_vsn_str)
  739.         self._output(str)
  740.         if self._http_vsn == 11:
  741.             if not skip_host:
  742.                 netloc = ''
  743.                 if url.startswith('http'):
  744.                     (nil, netloc, nil, nil, nil) = urlsplit(url)
  745.                 
  746.                 if netloc:
  747.                     
  748.                     try:
  749.                         netloc_enc = netloc.encode('ascii')
  750.                     except UnicodeEncodeError:
  751.                         netloc_enc = netloc.encode('idna')
  752.  
  753.                     self.putheader('Host', netloc_enc)
  754.                 else:
  755.                     
  756.                     try:
  757.                         host_enc = self.host.encode('ascii')
  758.                     except UnicodeEncodeError:
  759.                         host_enc = self.host.encode('idna')
  760.  
  761.                     if self.port == HTTP_PORT:
  762.                         self.putheader('Host', host_enc)
  763.                     else:
  764.                         self.putheader('Host', '%s:%s' % (host_enc, self.port))
  765.             
  766.             if not skip_accept_encoding:
  767.                 self.putheader('Accept-Encoding', 'identity')
  768.             
  769.         
  770.  
  771.     
  772.     def putheader(self, header, value):
  773.         """Send a request header line to the server.
  774.  
  775.         For example: h.putheader('Accept', 'text/html')
  776.         """
  777.         if self._HTTPConnection__state != _CS_REQ_STARTED:
  778.             raise CannotSendHeader()
  779.         
  780.         str = '%s: %s' % (header, value)
  781.         self._output(str)
  782.  
  783.     
  784.     def endheaders(self):
  785.         '''Indicate that the last header line has been sent to the server.'''
  786.         if self._HTTPConnection__state == _CS_REQ_STARTED:
  787.             self._HTTPConnection__state = _CS_REQ_SENT
  788.         else:
  789.             raise CannotSendHeader()
  790.         self._send_output()
  791.  
  792.     
  793.     def request(self, method, url, body = None, headers = { }):
  794.         '''Send a complete request to the server.'''
  795.         
  796.         try:
  797.             self._send_request(method, url, body, headers)
  798.         except socket.error:
  799.             v = None
  800.             if v[0] != 32 or not (self.auto_open):
  801.                 raise 
  802.             
  803.             self._send_request(method, url, body, headers)
  804.  
  805.  
  806.     
  807.     def _send_request(self, method, url, body, headers):
  808.         header_names = []([ k.lower() for k in headers ])
  809.         skips = { }
  810.         if 'accept-encoding' in header_names:
  811.             skips['skip_accept_encoding'] = 1
  812.         
  813.         self.putrequest(method, url, **skips)
  814.         if body and 'content-length' not in header_names:
  815.             self.putheader('Content-Length', str(len(body)))
  816.         
  817.         for hdr, value in headers.iteritems():
  818.             self.putheader(hdr, value)
  819.         
  820.         self.endheaders()
  821.         if body:
  822.             self.send(body)
  823.         
  824.  
  825.     
  826.     def getresponse(self):
  827.         '''Get the response from the server.'''
  828.         if self._HTTPConnection__response and self._HTTPConnection__response.isclosed():
  829.             self._HTTPConnection__response = None
  830.         
  831.         if self._HTTPConnection__state != _CS_REQ_SENT or self._HTTPConnection__response:
  832.             raise ResponseNotReady()
  833.         
  834.         if self.debuglevel > 0:
  835.             response = self.response_class(self.sock, self.debuglevel, strict = self.strict, method = self._method)
  836.         else:
  837.             response = self.response_class(self.sock, strict = self.strict, method = self._method)
  838.         response.begin()
  839.         if not response.will_close != _UNKNOWN:
  840.             raise AssertionError
  841.         self._HTTPConnection__state = _CS_IDLE
  842.         if response.will_close:
  843.             self.close()
  844.         else:
  845.             self._HTTPConnection__response = response
  846.         return response
  847.  
  848.  
  849.  
  850. class SharedSocket:
  851.     
  852.     def __init__(self, sock):
  853.         self.sock = sock
  854.         self._refcnt = 0
  855.  
  856.     
  857.     def incref(self):
  858.         self._refcnt += 1
  859.  
  860.     
  861.     def decref(self):
  862.         self._refcnt -= 1
  863.         if not self._refcnt >= 0:
  864.             raise AssertionError
  865.         self
  866.         if self._refcnt == 0:
  867.             self.sock.close()
  868.         
  869.  
  870.     
  871.     def __del__(self):
  872.         self.sock.close()
  873.  
  874.  
  875.  
  876. class SharedSocketClient:
  877.     
  878.     def __init__(self, shared):
  879.         self._closed = 0
  880.         self._shared = shared
  881.         self._shared.incref()
  882.         self._sock = shared.sock
  883.  
  884.     
  885.     def close(self):
  886.         if not self._closed:
  887.             self._shared.decref()
  888.             self._closed = 1
  889.             self._shared = None
  890.         
  891.  
  892.  
  893.  
  894. class SSLFile(SharedSocketClient):
  895.     '''File-like object wrapping an SSL socket.'''
  896.     BUFSIZE = 8192
  897.     
  898.     def __init__(self, sock, ssl, bufsize = None):
  899.         SharedSocketClient.__init__(self, sock)
  900.         self._ssl = ssl
  901.         self._buf = ''
  902.         if not bufsize:
  903.             pass
  904.         self._bufsize = self.__class__.BUFSIZE
  905.  
  906.     
  907.     def _read(self):
  908.         buf = ''
  909.         while True:
  910.             
  911.             try:
  912.                 buf = self._ssl.read(self._bufsize)
  913.             except socket.sslerror:
  914.                 err = None
  915.                 if err[0] == socket.SSL_ERROR_WANT_READ or err[0] == socket.SSL_ERROR_WANT_WRITE:
  916.                     continue
  917.                 
  918.                 if err[0] == socket.SSL_ERROR_ZERO_RETURN or err[0] == socket.SSL_ERROR_EOF:
  919.                     break
  920.                 
  921.                 raise 
  922.                 continue
  923.                 except socket.error:
  924.                     err = None
  925.                     if err[0] == errno.EINTR:
  926.                         continue
  927.                     
  928.                     if err[0] == errno.EBADF:
  929.                         break
  930.                     
  931.                     raise 
  932.                     continue
  933.                 else:
  934.                     break
  935.                 None<EXCEPTION MATCH>socket.error
  936.             return buf
  937.  
  938.  
  939.     
  940.     def read(self, size = None):
  941.         L = [
  942.             self._buf]
  943.         avail = len(self._buf)
  944.         while size is None or avail < size:
  945.             s = self._read()
  946.             if s == '':
  947.                 break
  948.             
  949.             L.append(s)
  950.             avail += len(s)
  951.         all = ''.join(L)
  952.         if size is None:
  953.             self._buf = ''
  954.             return all
  955.         else:
  956.             self._buf = all[size:]
  957.             return all[:size]
  958.  
  959.     
  960.     def readline(self):
  961.         L = [
  962.             self._buf]
  963.         self._buf = ''
  964.         while None:
  965.             i = L[-1].find('\n')
  966.             if i >= 0:
  967.                 break
  968.             
  969.             s = self._read()
  970.             if s == '':
  971.                 break
  972.             
  973.             continue
  974.             if i == -1:
  975.                 return ''.join(L)
  976.             else:
  977.                 all = ''.join(L)
  978.                 i = all.find('\n') + 1
  979.                 line = all[:i]
  980.                 self._buf = all[i:]
  981.                 return line
  982.  
  983.     
  984.     def readlines(self, sizehint = 0):
  985.         total = 0
  986.         list = []
  987.         while True:
  988.             line = self.readline()
  989.             if not line:
  990.                 break
  991.             
  992.             list.append(line)
  993.             total += len(line)
  994.             if sizehint and total >= sizehint:
  995.                 break
  996.                 continue
  997.         return list
  998.  
  999.     
  1000.     def fileno(self):
  1001.         return self._sock.fileno()
  1002.  
  1003.     
  1004.     def __iter__(self):
  1005.         return self
  1006.  
  1007.     
  1008.     def next(self):
  1009.         line = self.readline()
  1010.         if not line:
  1011.             raise StopIteration
  1012.         
  1013.         return line
  1014.  
  1015.  
  1016.  
  1017. class FakeSocket(SharedSocketClient):
  1018.     
  1019.     class _closedsocket:
  1020.         
  1021.         def __getattr__(self, name):
  1022.             raise error(9, 'Bad file descriptor')
  1023.  
  1024.  
  1025.     
  1026.     def __init__(self, sock, ssl):
  1027.         sock = SharedSocket(sock)
  1028.         SharedSocketClient.__init__(self, sock)
  1029.         self._ssl = ssl
  1030.  
  1031.     
  1032.     def close(self):
  1033.         SharedSocketClient.close(self)
  1034.         self._sock = self.__class__._closedsocket()
  1035.  
  1036.     
  1037.     def makefile(self, mode, bufsize = None):
  1038.         if mode != 'r' and mode != 'rb':
  1039.             raise UnimplementedFileMode()
  1040.         
  1041.         return SSLFile(self._shared, self._ssl, bufsize)
  1042.  
  1043.     
  1044.     def send(self, stuff, flags = 0):
  1045.         return self._ssl.write(stuff)
  1046.  
  1047.     sendall = send
  1048.     
  1049.     def recv(self, len = 1024, flags = 0):
  1050.         return self._ssl.read(len)
  1051.  
  1052.     
  1053.     def __getattr__(self, attr):
  1054.         return getattr(self._sock, attr)
  1055.  
  1056.  
  1057.  
  1058. class HTTPSConnection(HTTPConnection):
  1059.     '''This class allows communication via SSL.'''
  1060.     default_port = HTTPS_PORT
  1061.     
  1062.     def __init__(self, host, port = None, key_file = None, cert_file = None, strict = None):
  1063.         HTTPConnection.__init__(self, host, port, strict)
  1064.         self.key_file = key_file
  1065.         self.cert_file = cert_file
  1066.  
  1067.     
  1068.     def connect(self):
  1069.         '''Connect to a host on a given (SSL) port.'''
  1070.         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1071.         sock.connect((self.host, self.port))
  1072.         ssl = socket.ssl(sock, self.key_file, self.cert_file)
  1073.         self.sock = FakeSocket(sock, ssl)
  1074.  
  1075.  
  1076.  
  1077. class HTTP:
  1078.     '''Compatibility class with httplib.py from 1.5.'''
  1079.     _http_vsn = 10
  1080.     _http_vsn_str = 'HTTP/1.0'
  1081.     debuglevel = 0
  1082.     _connection_class = HTTPConnection
  1083.     
  1084.     def __init__(self, host = '', port = None, strict = None):
  1085.         '''Provide a default host, since the superclass requires one.'''
  1086.         if port == 0:
  1087.             port = None
  1088.         
  1089.         self._setup(self._connection_class(host, port, strict))
  1090.  
  1091.     
  1092.     def _setup(self, conn):
  1093.         self._conn = conn
  1094.         self.send = conn.send
  1095.         self.putrequest = conn.putrequest
  1096.         self.endheaders = conn.endheaders
  1097.         self.set_debuglevel = conn.set_debuglevel
  1098.         conn._http_vsn = self._http_vsn
  1099.         conn._http_vsn_str = self._http_vsn_str
  1100.         self.file = None
  1101.  
  1102.     
  1103.     def connect(self, host = None, port = None):
  1104.         """Accept arguments to set the host/port, since the superclass doesn't."""
  1105.         if host is not None:
  1106.             self._conn._set_hostport(host, port)
  1107.         
  1108.         self._conn.connect()
  1109.  
  1110.     
  1111.     def getfile(self):
  1112.         """Provide a getfile, since the superclass' does not use this concept."""
  1113.         return self.file
  1114.  
  1115.     
  1116.     def putheader(self, header, *values):
  1117.         '''The superclass allows only one value argument.'''
  1118.         self._conn.putheader(header, '\r\n\t'.join(values))
  1119.  
  1120.     
  1121.     def getreply(self):
  1122.         '''Compat definition since superclass does not define it.
  1123.  
  1124.         Returns a tuple consisting of:
  1125.         - server status code (e.g. \'200\' if all goes well)
  1126.         - server "reason" corresponding to status code
  1127.         - any RFC822 headers in the response from the server
  1128.         '''
  1129.         
  1130.         try:
  1131.             response = self._conn.getresponse()
  1132.         except BadStatusLine:
  1133.             e = None
  1134.             self.file = self._conn.sock.makefile('rb', 0)
  1135.             self.close()
  1136.             self.headers = None
  1137.             return (-1, e.line, None)
  1138.  
  1139.         self.headers = response.msg
  1140.         self.file = response.fp
  1141.         return (response.status, response.reason, response.msg)
  1142.  
  1143.     
  1144.     def close(self):
  1145.         self._conn.close()
  1146.         self.file = None
  1147.  
  1148.  
  1149. if hasattr(socket, 'ssl'):
  1150.     
  1151.     class HTTPS(HTTP):
  1152.         '''Compatibility with 1.5 httplib interface
  1153.  
  1154.         Python 1.5.2 did not have an HTTPS class, but it defined an
  1155.         interface for sending http requests that is also useful for
  1156.         https.
  1157.         '''
  1158.         _connection_class = HTTPSConnection
  1159.         
  1160.         def __init__(self, host = '', port = None, key_file = None, cert_file = None, strict = None):
  1161.             if port == 0:
  1162.                 port = None
  1163.             
  1164.             self._setup(self._connection_class(host, port, key_file, cert_file, strict))
  1165.             self.key_file = key_file
  1166.             self.cert_file = cert_file
  1167.  
  1168.  
  1169.  
  1170.  
  1171. class HTTPException(Exception):
  1172.     pass
  1173.  
  1174.  
  1175. class NotConnected(HTTPException):
  1176.     pass
  1177.  
  1178.  
  1179. class InvalidURL(HTTPException):
  1180.     pass
  1181.  
  1182.  
  1183. class UnknownProtocol(HTTPException):
  1184.     
  1185.     def __init__(self, version):
  1186.         self.args = (version,)
  1187.         self.version = version
  1188.  
  1189.  
  1190.  
  1191. class UnknownTransferEncoding(HTTPException):
  1192.     pass
  1193.  
  1194.  
  1195. class UnimplementedFileMode(HTTPException):
  1196.     pass
  1197.  
  1198.  
  1199. class IncompleteRead(HTTPException):
  1200.     
  1201.     def __init__(self, partial):
  1202.         self.args = (partial,)
  1203.         self.partial = partial
  1204.  
  1205.  
  1206.  
  1207. class ImproperConnectionState(HTTPException):
  1208.     pass
  1209.  
  1210.  
  1211. class CannotSendRequest(ImproperConnectionState):
  1212.     pass
  1213.  
  1214.  
  1215. class CannotSendHeader(ImproperConnectionState):
  1216.     pass
  1217.  
  1218.  
  1219. class ResponseNotReady(ImproperConnectionState):
  1220.     pass
  1221.  
  1222.  
  1223. class BadStatusLine(HTTPException):
  1224.     
  1225.     def __init__(self, line):
  1226.         self.args = (line,)
  1227.         self.line = line
  1228.  
  1229.  
  1230. error = HTTPException
  1231.  
  1232. class LineAndFileWrapper:
  1233.     '''A limited file-like object for HTTP/0.9 responses.'''
  1234.     
  1235.     def __init__(self, line, file):
  1236.         self._line = line
  1237.         self._file = file
  1238.         self._line_consumed = 0
  1239.         self._line_offset = 0
  1240.         self._line_left = len(line)
  1241.  
  1242.     
  1243.     def __getattr__(self, attr):
  1244.         return getattr(self._file, attr)
  1245.  
  1246.     
  1247.     def _done(self):
  1248.         self._line_consumed = 1
  1249.         self.read = self._file.read
  1250.         self.readline = self._file.readline
  1251.         self.readlines = self._file.readlines
  1252.  
  1253.     
  1254.     def read(self, amt = None):
  1255.         if self._line_consumed:
  1256.             return self._file.read(amt)
  1257.         
  1258.         if not self._line_left:
  1259.             raise AssertionError
  1260.         if amt is None or amt > self._line_left:
  1261.             s = self._line[self._line_offset:]
  1262.             self._done()
  1263.             if amt is None:
  1264.                 return s + self._file.read()
  1265.             else:
  1266.                 return s + self._file.read(amt - len(s))
  1267.         elif not amt <= self._line_left:
  1268.             raise AssertionError
  1269.         i = self._line_offset
  1270.         j = i + amt
  1271.         s = self._line[i:j]
  1272.         self._line_offset = j
  1273.         self._line_left -= amt
  1274.         if self._line_left == 0:
  1275.             self._done()
  1276.         
  1277.         return s
  1278.  
  1279.     
  1280.     def readline(self):
  1281.         if self._line_consumed:
  1282.             return self._file.readline()
  1283.         
  1284.         if not self._line_left:
  1285.             raise AssertionError
  1286.         s = self._line[self._line_offset:]
  1287.         self._done()
  1288.         return s
  1289.  
  1290.     
  1291.     def readlines(self, size = None):
  1292.         if self._line_consumed:
  1293.             return self._file.readlines(size)
  1294.         
  1295.         if not self._line_left:
  1296.             raise AssertionError
  1297.         L = [
  1298.             self._line[self._line_offset:]]
  1299.         self._done()
  1300.         if size is None:
  1301.             return L + self._file.readlines()
  1302.         else:
  1303.             return L + self._file.readlines(size)
  1304.  
  1305.  
  1306.  
  1307. def test():
  1308.     '''Test this module.
  1309.  
  1310.     A hodge podge of tests collected here, because they have too many
  1311.     external dependencies for the regular test suite.
  1312.     '''
  1313.     import sys as sys
  1314.     import getopt as getopt
  1315.     (opts, args) = getopt.getopt(sys.argv[1:], 'd')
  1316.     dl = 0
  1317.     for o, a in opts:
  1318.         if o == '-d':
  1319.             dl = dl + 1
  1320.             continue
  1321.     
  1322.     host = 'www.python.org'
  1323.     selector = '/'
  1324.     if args[0:]:
  1325.         host = args[0]
  1326.     
  1327.     if args[1:]:
  1328.         selector = args[1]
  1329.     
  1330.     h = HTTP()
  1331.     h.set_debuglevel(dl)
  1332.     h.connect(host)
  1333.     h.putrequest('GET', selector)
  1334.     h.endheaders()
  1335.     (status, reason, headers) = h.getreply()
  1336.     print 'status =', status
  1337.     print 'reason =', reason
  1338.     print 'read', len(h.getfile().read())
  1339.     print 
  1340.     if headers:
  1341.         for header in headers.headers:
  1342.             print header.strip()
  1343.         
  1344.     
  1345.     print 
  1346.     
  1347.     class HTTP11(HTTP):
  1348.         _http_vsn = 11
  1349.         _http_vsn_str = 'HTTP/1.1'
  1350.  
  1351.     h = HTTP11('www.python.org')
  1352.     h.putrequest('GET', 'http://www.python.org/~jeremy/')
  1353.     h.endheaders()
  1354.     h.getreply()
  1355.     h.close()
  1356.     if hasattr(socket, 'ssl'):
  1357.         for host, selector in (('sourceforge.net', '/projects/python'),):
  1358.             print 'https://%s%s' % (host, selector)
  1359.             hs = HTTPS()
  1360.             hs.set_debuglevel(dl)
  1361.             hs.connect(host)
  1362.             hs.putrequest('GET', selector)
  1363.             hs.endheaders()
  1364.             (status, reason, headers) = hs.getreply()
  1365.             print 'status =', status
  1366.             print 'reason =', reason
  1367.             print 'read', len(hs.getfile().read())
  1368.             print 
  1369.             if headers:
  1370.                 for header in headers.headers:
  1371.                     print header.strip()
  1372.                 
  1373.             
  1374.             print 
  1375.         
  1376.     
  1377.  
  1378. if __name__ == '__main__':
  1379.     test()
  1380.  
  1381.